﻿using System.Linq;
using VO;
using System.Collections.Generic;
using System;

namespace DAL
{
    public class RegraAtendimentoDAL
    {

        #region Insert
        public int Insert(RegraAtendimento obj)
        {
            var contexto = new CallcenterEntities();
            var objC = new tbCCRegraAtendimento();
            objC = PopulaObjeto(obj, objC);
            contexto.AddTotbCCRegraAtendimento(objC);
            contexto.SaveChanges();
            return objC.idRegraCallCenter;
        }
        #endregion

        #region Update
        public void Update(RegraAtendimento obj)
        {
            var contexto = new CallcenterEntities();
            var regra = (from regraAux in contexto.tbCCRegraAtendimento
                         where regraAux.idRegraCallCenter == obj.idRegraCallCenter
                         select regraAux).FirstOrDefault();
            PopulaObjeto(obj, regra);
            contexto.SaveChanges();
        }
        #endregion

        #region UpdateStatus
        public void UpdateStatus(RegraAtendimento obj)
        {
            using (var contexto = new CallcenterEntities())
            {
                var regra = (from regraAux in contexto.tbCCRegraAtendimento
                             where regraAux.idRegraCallCenter == obj.idRegraCallCenter
                             select regraAux).FirstOrDefault();
                regra.fgAtivo = obj.fgAtivo;
                contexto.SaveChanges();
            }
        }
        #endregion

        #region Delete
        public void Delete(int idRegra)
        {
            var contexto = new CallcenterEntities();
            tbCCRegraAtendimento regra = (from regraAux in contexto.tbCCRegraAtendimento
                         where regraAux.idRegraCallCenter == idRegra
                         select regraAux).FirstOrDefault();
            contexto.DeleteObject(regra);
            contexto.SaveChanges();
        }
        #endregion

        #region FinalizaAtendimento
        public void FinalizaAtendimento(RegraAtendimento obRegra)
        {
            using (var data = new CallcenterEntities())
            {
                var obHistoricoAtendimento = new HistoricoAtendimento();
                var obHistoricoAtendimentoDal = new HistoricoAtendimentoDAL();

                obHistoricoAtendimento.idCampanha = obRegra.idCampanha;
                obHistoricoAtendimento.idCliente = obRegra.idCliente;
                obHistoricoAtendimento.idOperador = obRegra.idOperador;
                obHistoricoAtendimento.idStatus = obRegra.idStatus;


                var historico = obHistoricoAtendimentoDal.selectHistoricoAtendimento(obHistoricoAtendimento);
                var totHistorico = historico.Count();//Retorna o total de vezes que esse atendimento ja passou pelo mesmo status

                var obCampanhaStatusDal = new CampanhaStatusDAL();

                var acaoAtendimento = obCampanhaStatusDal.Select(obRegra.idCampanha, obRegra.idStatus).FirstOrDefault();

                if (acaoAtendimento != null)
                {
                    var obCampanhaStatusRegraDal = new CampanhaStatusDAL();

                    var listRegraStatus = obCampanhaStatusRegraDal.SelectRegra(obRegra.idCampanha, obRegra.idStatus, totHistorico);
                    //var listRegraStatus = obCampanhaStatusRegraDal.Select(acaoAtendimento.idCampanhaStatus);

                    //verificamos todas as regras aplicada 
                    if (listRegraStatus!=null)
                    {
                        foreach (var item in listRegraStatus)
                        {
                            //var sigla = Select(item.idRegra).FirstOrDefault().Sigla;

                            #region antigo com tabela de tbCCStatusIncidencia

                            //int RegraAtendimento = Select(idregra).First().idRegraCallCenter;

                            //var statusIncidencia = new StatusIncidencia();
                            //statusIncidencia.idCampanha = item.idRegra;
                            //statusIncidencia.qtd = totHistorico;
                            //var statusIncidenciaDal = new StatusIncidenciaDAL();

                            //qtd de dia que somaremos a dtReagendamento
                            //var valorAux = statusIncidenciaDal.Select(statusIncidencia).FirstOrDefault();


                            //obRegra.dtReAgendamento = DateTime.Now;

                            #endregion


                            if (listRegraStatus != null)
                            {
                                obRegra.qtdDiasRegras = item.Dias;
                            }

                            switch (item.SiglasRegra)
                            {
                                case "AGE": //Agendamento
                                    AgendaAtendimento(obRegra);
                                    break;
                                case "DES": //Desvicular
                                    DesviculaAtendimento(obRegra);
                                    break;
                                case "BLA": //Blacklist
                                    BlackList(obRegra);
                                    break;
                            }
                        }
                    }
                    else
                        throw new Exception("Não há status para o historico deste Cliente");
                }
                else
                    throw new Exception("Não há status para esta campanha");
            }
        }
        #endregion

        #region BlackList
        private static void BlackList(RegraAtendimento obRegra)
        {
            var obBl = new Blacklist
                           {
                               idCliente = obRegra.idCliente,
                               idAtendente = obRegra.idOperador,
                               idCampanha = obRegra.idCampanha,
                               dtCadastro = DateTime.Now,
                               cpf = obRegra.cpf
                           };

            var obBlDal = new BlacklistDAL();
            obBlDal.Insert(obBl);

            DesviculaAtendimento(obRegra);
        }
        #endregion

        #region DesviculaAtendimento
        private static void DesviculaAtendimento(RegraAtendimento obRegra)
        {
            var obFila = new Fila();
            var obDesFilaDAL = new FilaDAL();
            obFila.idFila = obRegra.idFila;
            obDesFilaDAL.RemoveFila(obFila);//desviculado o cliente da fila
        }
        #endregion

        #region AgendaAtendimento
        private static void AgendaAtendimento(RegraAtendimento obRegra)
        {
            var objnewRegra = new ClienteAgendamento
            {
                IdCampanha = obRegra.idCampanha,
                IdCliente = obRegra.idCliente
            };

            if (obRegra.blnAgendamento)
            {
                objnewRegra.DataAgendamento = obRegra.dtReAgendamento;
            }
            else
            {
                var dtAgendamento = obRegra.dtReAgendamento.AddHours(obRegra.qtdDiasRegras * 24);
                var blDia = false;
                while (!blDia)
                {

                    var dia = new RegraAtendimentoDAL().SelectFeriado(obRegra.dtReAgendamento.Day.ToString(), obRegra.dtReAgendamento.Month.ToString());
                    if (dia.Count == 0)
                        blDia = true;
                    else
                        dtAgendamento = dtAgendamento.AddDays(1);
                }
                objnewRegra.DataAgendamento = dtAgendamento;
            }


            objnewRegra.idAtendente = obRegra.idOperador;
            var oAgendamento = new ClienteAgendamentoDAL();
            oAgendamento.InsereAgendamento(objnewRegra);
            

            var obFilaDAL = new FilaDAL();
            obFilaDAL.AgendaClienteFila(obRegra.idFila);
        }
        #endregion

        #region ReAgendaAtendimentoCliente
        private void ReAgendaAtendimentoCliente(RegraAtendimento obRegra, int qtdDiasRetorno)
        {
            
            var obClienteDAL = new ClienteDAL();
            var obCli = new Cliente
                            {
                                idCliente = obRegra.idCliente,
                                dtReagendamento = obRegra.dtReAgendamento.AddDays(qtdDiasRetorno)
                            };

            obClienteDAL.AlteraDataReAgendamento(obCli);
        }
        #endregion

        #region BloquearAtendimentoCliente
        private void BloquearAtendimentoCliente(int idCliente)
        {
            
            var obClienteDAL = new ClienteDAL();
            var obCli = new Cliente {idCliente = idCliente, fgAtivo = false};

            obClienteDAL.AlteraBloqueio(obCli);
        }
        #endregion

        #region Select
        public IList<RegraAtendimento> Select(int idRegra = 0)
        {
            var contexto = new CallcenterEntities();

            //IQueryable<tbCCRegraAtendimento> regra;

            var regra = (from statusAux in contexto.tbCCRegraAtendimento
                     where statusAux.fgAtivo && (statusAux.idRegraCallCenter == idRegra || idRegra == 0)
                     select statusAux);

            //Carrega lista
            var list = PopulaObjeto(regra);

            return list;
        }

        #endregion

        #region SelectAll
        public IList<RegraAtendimento> SelectAll()
        {
            var contexto = new CallcenterEntities();

            //IQueryable<tbCCRegraAtendimento> regra;

            var regra = (from statusAux in contexto.tbCCRegraAtendimento
                     select statusAux);

            //Carrega lista
            var list = PopulaObjeto(regra);

            return list;
        }
        #endregion

        #region PopulaObjeto
        protected static tbCCRegraAtendimento PopulaObjeto(RegraAtendimento obj, tbCCRegraAtendimento tabela)
        {
            tabela.DescricaoRegra = obj.DescricaoRegra;
            tabela.fgAtivo = obj.fgAtivo;
            tabela.idRegraCallCenter = obj.idRegraCallCenter;
            tabela.idStatus = obj.idStatus;
            tabela.NomeRegra = obj.NomeRegra;
            tabela.Sigla = obj.Sigla;
            return tabela;
        }

        protected static IList<RegraAtendimento> PopulaObjeto(IQueryable<tbCCRegraAtendimento> reader)
        {
            return reader.Select(obj => new RegraAtendimento
                                            {
                                                idRegraCallCenter = obj.idRegraCallCenter, 
                                                NomeRegra = obj.NomeRegra,
                                                DescricaoRegra = obj.DescricaoRegra, 
                                                Sigla = obj.Sigla, 
                                                idStatus = (int) obj.idStatus, 
                                                fgAtivo = obj.fgAtivo
                                            }).ToList();
        }
        #endregion



        #region SelectFeriado
        public  IList<Feriado> SelectFeriado(string Dia,string Mes)
        {
            var contexto = new CallcenterEntities();

            //IQueryable<tbCCFeriado> regra;

            var regra = (from strFeriado in contexto.tbCCFeriado
                     where (strFeriado.diaFeriado == Dia && strFeriado.mesFeriado == Mes)
                     select strFeriado);

            //Carrega lista
            var list = PopulaObjetoFeriado(regra);

            return list;
        }
        protected static IList<Feriado> PopulaObjetoFeriado(IQueryable<tbCCFeriado> reader)
        {
            var list = new List<Feriado>();
            foreach (var obj in reader)
            {
                var newObj = new Feriado
                                 {
                                     nomeFeirado = obj.nomeFeriado,
                                     Mes = obj.mesFeriado,
                                     Dia = obj.diaFeriado,
                                     idUsuario = (int) obj.idUsuarioCadastro,
                                     fgNacional = (bool) obj.fgNacional
                                 };

                list.Add(newObj);
            }
            return list;
        }


        #endregion

    }
}